package com.gcu.drivingschool.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gcu.drivingschool.domain.dto.PageBean;
import com.gcu.drivingschool.domain.po.BookDriving;
import com.gcu.drivingschool.domain.po.Coach;
import com.gcu.drivingschool.domain.po.Student;
import com.gcu.drivingschool.domain.vo.BookDrivingVo;
import com.gcu.drivingschool.domain.vo.Result;
import com.gcu.drivingschool.service.BookDrivingService;
import com.gcu.drivingschool.service.CoachService;
import com.gcu.drivingschool.service.StudentService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 预约学车控制器
 *
 * @author zzr
 * @since 2024-05-12
 */
@Tag(name = "预约学车控制器", description = "预约学车控制器")
@RestController
@RequestMapping("/api/bookDrivings")
@RequiredArgsConstructor
public class BookDrivingController {
    private final BookDrivingService bookDrivingService;
    private final StudentService studentService;
    private final CoachService coachService;

    /**
     * 预约学车
     *
     * @return
     */
    @Operation(summary = "预约学车", description = "预约学车学员需存在且该学员已报名教练<br/>" +
            "同一天只允许学员预约一次")
    @PostMapping
    public Result book(@Validated @RequestBody BookDriving bookDriving) {
        Student s = studentService.getById(bookDriving.getStudentId());
        if (s == null) {
            return Result.fail("学员不存在");
        }
        if (s.getCoachId() == null) {
            return Result.fail("请先报名教练");
        }
        try {
            bookDriving.setStatus("未过期");
            bookDrivingService.save(bookDriving);
            return Result.success();
        } catch (DuplicateKeyException e) {
            return Result.fail("您已预约该日期，请勿重复预约");
        }
    }

    /**
     * 取消预约
     *
     * @param id
     * @return
     */
    @Parameter(name = "id", description = "预约记录id", in = ParameterIn.PATH, required = true)
    @Operation(summary = "取消预约", description = "删除学车预约记录")
    @DeleteMapping("/{id}")
    public Result cancelBook(@PathVariable("id") Integer id) {
        boolean remove = bookDrivingService.removeById(id);
        if (!remove) {
            return Result.fail();
        }
        return Result.success();
    }


    /**
     * 获取预约学车记录条数
     * @param coachId
     * @param bookDate
     * @return
     */
    @Parameters({
            @Parameter(name = "bookDate", description = "预约日期", in = ParameterIn.QUERY),
            @Parameter(name = "coachId", description = "教练id", in = ParameterIn.QUERY)
    })
    @Operation(summary = "获取预约学车记录条数", description = "哪个参数不填代表所有<br/>"+
            "都不填参数：查询所有学员所有日期预约记录条数<br/>" +
            "填写日期：查询该日期所有学员预约记录条数<br/>" +"填写教练id：查询该教练所带学员所有日期预约记录条数<br/>" +
            "填写日期和教练id：查询该教练所带学员该日期预约记录条数")
    @GetMapping("/count")
    public Result getCountByDateAndCoachId(@RequestParam(required = false) Integer coachId,
                                           @RequestParam(required = false) String bookDate) {
        LambdaQueryWrapper<BookDriving> wrapper = new LambdaQueryWrapper();
        long count = 0;
        if (coachId!=null) {
            //查询教练所有学员id
            List<Integer> sIds = studentService.lambdaQuery().eq(Student::getCoachId, coachId).list()
                    .stream().mapToInt(Student::getId).boxed().collect(Collectors.toList());
            if (sIds.size() > 0) {
                wrapper.in(BookDriving::getStudentId, sIds);
            }else {
                return Result.success(count);
            }
        }
        if (StringUtils.isNotBlank(bookDate)) {
            wrapper.eq(BookDriving::getBookDate, LocalDate.parse(bookDate));
        }
        count= bookDrivingService.count(wrapper);
        return Result.success(count);
    }

    /**
     * 查询预约学车记录列表
     * @param pageNum
     * @param pageSize
     * @param studentId
     * @param coachId
     * @param bookDate
     * @return
     */
    @Parameters({
            @Parameter(name = "pageNum", description = "第几页", in = ParameterIn.QUERY),
            @Parameter(name = "pageSize", description = "每页条数", in = ParameterIn.QUERY),
            @Parameter(name = "studentId", description = "学员id", in = ParameterIn.QUERY),
            @Parameter(name = "coachId", description = "教练id", in = ParameterIn.QUERY),
            @Parameter(name = "bookDate", description = "预约日期", in = ParameterIn.QUERY)
    })
    @Operation(summary = "查询预约学车记录列表", description = "哪个参数不填代表所有<br/>"+
            "都不填参数：查询所有预约学车记录<br/>" +
            "填写学员id：查询该学员预约学车记录<br/>" +"填写教练id：查询该教练所带学员所有预约学车记录<br/>" +
            "填写日期：查询该日期所有预约学车记录<br/>"+"...自行组合<br/>")
    @GetMapping
    public Result getBookDrivingList(@RequestParam(required = false) Integer pageNum,
                                     @RequestParam(required = false) Integer pageSize,
                                     @RequestParam(required = false) Integer studentId,
                                     @RequestParam(required = false) Integer coachId,
                                     @RequestParam(required = false) String bookDate) {
        //如果不传pageNum和pageSize,不分页
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = Integer.MAX_VALUE;
        }
        PageBean pb = new PageBean(0L,new ArrayList());
        LambdaQueryWrapper<BookDriving> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(studentId != null, BookDriving::getStudentId, studentId);
        if (coachId != null) {
            //查询教练所有学员id
            List<Integer> sIds = studentService.lambdaQuery().eq(Student::getCoachId, coachId).list()
                    .stream().mapToInt(Student::getId).boxed().collect(Collectors.toList());
            if (sIds.size()>0) {
                wrapper.in(BookDriving::getStudentId, sIds);
            }else {
                return Result.success(pb);
            }
        }
        if (StringUtils.isNotBlank(bookDate)) {
            wrapper.eq(BookDriving::getBookDate, LocalDate.parse(bookDate));
        }
        PageHelper.startPage(pageNum, pageSize);//分页
        //查询数据
        List<BookDriving> list = bookDrivingService.list(wrapper);
        Page p = (Page) list;
        List<BookDriving> r = p.getResult();
        List<BookDrivingVo> l = new ArrayList<>();
        //查询该记录学员和教练详细信息（也可用联表查询）
        for (BookDriving b : r) {
            Student student = studentService.getById(b.getStudentId());
            Coach coach = coachService.getById(student.getCoachId());
            BookDrivingVo bookDrivingVo = new BookDrivingVo(b.getId(), student.getId(), student.getName(), student.getTelephone(),
                    coach.getId(), coach.getName(), coach.getTelephone(), coach.getPhoto(), coach.getType(),
                    coach.getCarNumber(), coach.getCarType(), b.getBookDate(),b.getStatus());
            l.add(bookDrivingVo);
        }
        pb = new PageBean(p.getTotal(), l);
        return Result.success(pb);
    }


}
